/*
 * WeightedDistribution.cpp
 *
 *  Created on: 24.11.2011
 *      Author: jan
 */

#include "WeightedDistribution.h"

namespace std {

WeightedDistribution::WeightedDistribution(vector<Particle> p) : states(),accum(0.0) {
	int n = 0;
	for(unsigned int i = 0; i < p.size(); i++){
		if(p[i].w > 0){
			accum += p[i].w;
			n++;
		}
	}
	double interval = 0;
	double target = 0;
	double uniformWeight = 1.0 / n;
//	cout << "N: " << n << endl;
//	cout << "accum: " << accum << endl;
	interval = accum / n;
//	cout << "interval " << interval << endl;
	double randval = UNIFORM_RAND;
//	cout << "randval " << randval << endl;
	target = interval * randval;
//	cout << "target: " << target << endl;
	accum = 0;
	if( isNotANan(interval)){
//		cout << "interval " << interval << endl;
		for (unsigned int i = 0; i < p.size(); i++) {
			if (p[i].w > 0) {
				accum += p[i].w;
				while(accum>target){
					p[i].w = uniformWeight;
					this->states.push_back(p[i]);
					target += interval;
				}
			}
		}
	}
}

bool WeightedDistribution::isNotANan(double i){
	return (i == i); // nan == nan ist immer false... daher
}

WeightedDistribution::~WeightedDistribution() {

}

Particle WeightedDistribution::pick(){
	if(states.size() > 0){
		return states[(int)((UNIFORM_RAND_WITHOUT_ONE)*states.size())];
	}
	return Particle(Point(-1,-1));
}

} /* namespace std */
